//
//  CXHTopOnNativeExpressAdapter.m
//  CXHAdSDK-TopOn
//
//  Created by 陈坤 on 2024/10/11.
//

#import "CXHTopOnNativeExpressAdapter.h"
#import "CXHTopOnNativeExpressEvent.h"
#import "CXHTopOnNativeEvent.h"
#import "CXHTopOnNativeExpressRenderer.h"
#import "CXHTopOnCommonBiddingManager.h"
#import "CXHTopOnCommonBiddingRequest.h"
#if __has_include(<AnyThinkSDK/AnyThinkSDK.h>)
#import <AnyThinkSDK/AnyThinkSDK.h>
#else
#import "AnyThinkSDK.h"
#endif
#import <CXHAdSDK-Core/CXHAdSDK.h>
#import <CXHAdSDK-Core/CXHAdSDKNativeExpressAd.h>
#import <CXHAdSDK-Core/CXHAdSDKNativeAd.h>
#import <CXHAdSDK-Kit/CXHUtilsKit.h>

@interface CXHTopOnNativeExpressAdapter ()

@property(nonatomic, strong) CXHTopOnNativeExpressEvent *expressCustomEvent;
@property (nonatomic, strong) CXHTopOnNativeEvent *nativeCustomEvent;

@property (nonatomic, strong) CXHAdSDKNativeExpressAd *nativeExpressAd;

@property (nonatomic, strong) CXHAdSDKNativeAd *nativeAd;

@property (nonatomic, assign) BOOL isC2SBinding;

@end

@implementation CXHTopOnNativeExpressAdapter

- (void)loadADWithArgument:(ATAdMediationArgument *)argument {
    BOOL isExpress = [argument.serverContentDic[@"isExpressAd"] boolValue];
    NSString *posid = argument.serverContentDic[@"posid"];
    
    if (isExpress) {
        self.expressCustomEvent = [[CXHTopOnNativeExpressEvent alloc] init];
        self.expressCustomEvent.adStatusBridge = self.adStatusBridge;
        self.expressCustomEvent.adMediationArgument = argument;
        
        
        CXHAdSDKNativeExpressType expressType = CXHAdSDKNativeExpressTypeImage;
        NSString *expressConfigType = [argument.serverContentDic CXH_objectOrNilForKey:@"expressType"];
        if (!kCXHStringIsEmpty(expressConfigType)) {
            if ([expressConfigType isEqualToString:@"left"]) {
                expressType = CXHAdSDKNativeExpressTypeLeft;
            }
            if ([expressConfigType isEqualToString:@"vimage"]) {
                expressType = CXHAdSDKNativeExpressTypeVerticalImage;
            }
        }
        
        CGSize adSize = CGSizeMake(CGRectGetWidth([UIScreen mainScreen].bounds) - 32, 10.0f);
        if (!CGSizeEqualToSize(argument.nativeSize, CGSizeZero)) {
            adSize = argument.nativeSize;
        }

        self.nativeExpressAd = [[CXHAdSDKNativeExpressAd alloc] initWithAdSize:adSize];
        self.nativeExpressAd.posId = posid;
        self.nativeExpressAd.delegate = self.expressCustomEvent;
        self.nativeExpressAd.controller = argument.viewController;
        self.nativeExpressAd.expressType = expressType;
        [self.nativeExpressAd load:[argument.serverContentDic[@"request_num"] intValue]];
    } else {
        self.nativeCustomEvent = [[CXHTopOnNativeEvent alloc] init];
        self.nativeCustomEvent.adStatusBridge = self.adStatusBridge;
        self.nativeCustomEvent.adMediationArgument = argument;
        
        // 自渲染
        self.nativeAd = [[CXHAdSDKNativeAd alloc] init];
        self.nativeAd.posId = posid;
        self.nativeAd.delegate = self.nativeCustomEvent;
        self.nativeAd.controller = argument.viewController;
        [self.nativeAd load:[argument.serverContentDic[@"request_num"] intValue]];
    }
}

#pragma mark - C2S Win Loss
- (void)didReceiveBidResult:(ATBidWinLossResult *)result{
    if (result.bidResultType == ATBidWinLossResultTypeWin) {
        if (self.nativeAd) {
            [self.nativeAd sendWinNotice:[result.winPrice integerValue]];
            return;
        }
        [self.nativeExpressAd sendWinNotice:[result.winPrice integerValue]];
        return;
    }
    if (self.nativeAd) {
        [self.nativeAd sendLossNotice:[result.secondPrice integerValue]];
        return;
    }
    [self.nativeExpressAd sendLossNotice:[result.secondPrice integerValue]];
}

- (void)loadADWithInfo:(nonnull NSDictionary *)serverInfo localInfo:(nonnull NSDictionary *)localInfo completion:(nonnull void (^)(NSArray<NSDictionary *> * _Nonnull, NSError * _Nonnull))completion {
    
    NSLog(@"------> menta start loadad");
    BOOL isExpress = [serverInfo[@"isExpressAd"] boolValue];
    NSString *bidId = serverInfo[kATAdapterCustomInfoBuyeruIdKey];
    NSString *posid = serverInfo[@"posid"];
    NSString *requestUUID = serverInfo[@"tracking_info_request_id"];
    UIViewController *controller = localInfo[@"cxh_controller"];
    
    if (bidId) {
        CXHTopOnCommonBiddingRequest *request = [[CXHTopOnCommonBiddingManager sharedInstance] getRequestItemWithUnitID:requestUUID];
        
        if (request) {
            if (isExpress) {
                self.expressCustomEvent = (CXHTopOnNativeExpressEvent *)request.customEvent;
                self.expressCustomEvent.requestCompletionBlock = completion;
                self.nativeExpressAd = request.customObject;
                       
                [self.expressCustomEvent nativeExpressAdLoadedWith:self.nativeExpressAd nativeExpressAdView:request.nativeAds.firstObject controller:controller];
            } else {
                self.nativeCustomEvent = (CXHTopOnNativeEvent *)request.customEvent;
                self.nativeCustomEvent.requestCompletionBlock = completion;
                self.nativeAd = request.customObject;
                
                [self.nativeCustomEvent nativeSelfRenderAdLoadedWith:self.nativeAd nativeAdModel:request.nativeAds.firstObject viewController:controller];
            }
        }
        [[CXHTopOnCommonBiddingManager sharedInstance] removeRequestItemWithUnitID:requestUUID];
        return;
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
        if (isExpress) {
            self.expressCustomEvent = [[CXHTopOnNativeExpressEvent alloc] initWithInfo:serverInfo localInfo:localInfo];
            self.expressCustomEvent.networkAdvertisingID = posid;
            self.expressCustomEvent.requestCompletionBlock = completion;
            CGSize adSize = CGSizeMake(CGRectGetWidth([UIScreen mainScreen].bounds) - 32, 10.0f);
            if ([localInfo[kATExtraInfoNativeAdSizeKey] respondsToSelector:@selector(CGSizeValue)]) {
                adSize = [localInfo[kATExtraInfoNativeAdSizeKey] CGSizeValue];
            }

            self.nativeExpressAd = [[CXHAdSDKNativeExpressAd alloc] initWithAdSize:adSize];
            self.nativeExpressAd.posId = posid;
            self.nativeExpressAd.delegate = self.expressCustomEvent;
            self.nativeExpressAd.controller = controller;
            [self.nativeExpressAd load:[serverInfo[@"request_num"] intValue]];
        } else {
            self.nativeCustomEvent = [[CXHTopOnNativeEvent alloc] initWithInfo:serverInfo localInfo:localInfo];
            self.nativeCustomEvent.networkAdvertisingID = posid;
            self.nativeCustomEvent.requestCompletionBlock = completion;
            
            // 自渲染
            self.nativeAd = [[CXHAdSDKNativeAd alloc] init];
            self.nativeAd.posId = posid;
            self.nativeAd.delegate = self.nativeCustomEvent;
            self.nativeAd.controller = controller;
            [self.nativeAd load:[serverInfo[@"request_num"] intValue]];
        }
    });
}

+ (BOOL)adReadyWithCustomObject:(nonnull id)customObject info:(nonnull NSDictionary *)info {
    return YES;
}

+ (BOOL)isSupportAdType:(nonnull ATUnitGroupModel *)unitGroupModel { 
    return YES;
}


+(Class) rendererClass {
    return [CXHTopOnNativeExpressRenderer class];
}

#pragma mark - Header bidding
#pragma mark - c2s
// 后台配置了C2S的竞价广告会先来到这个方法，完成相应的竞价请求
+ (void)bidRequestWithPlacementModel:(ATPlacementModel*)placementModel
                      unitGroupModel:(ATUnitGroupModel*)unitGroupModel
                                info:(NSDictionary*)info
                          completion:(void(^)(ATBidInfo *bidInfo, NSError *error))completion {
    NSLog(@"------> menta start bidding");
    NSString *appIDKey = @"appid";
    if([info.allKeys containsObject:@"appId"]) {
        appIDKey = @"appId";
    }
    NSString *appID = info[appIDKey];
    NSString *posid = info[@"posid"];
    BOOL isExpress = [info[@"isExpressAd"] boolValue];
    NSString *requestUUID = info[@"tracking_info_request_id"];
    NSLog(@"=====requestuuid%@", requestUUID);
    
    if (!posid && completion != nil) {
        NSError *err = [NSError errorWithDomain:@"com.menta.mediation.ios"
                                           code:1
                                       userInfo:@{NSLocalizedDescriptionKey:@"Bid request has failed", NSLocalizedFailureReasonErrorKey:@"Menta config is error"}];
        completion( nil, err);
        return;
    }
    
    if (!kCXHStringIsEmpty(appID)) {
        NSString *domain = [info CXH_objectOrNilForKey:@"domain"];
        [CXHTopOnNativeExpressAdapter initCXHSDKWith:appID domain:domain completion:^{}];
    }
    
    CXHTopOnCommonBiddingRequest *request = [[CXHTopOnCommonBiddingRequest alloc] init];
    request.unitGroup = unitGroupModel;
    request.placementID = placementModel.placementID;
    
    request.bidCompletion = completion;
    request.unitID = posid;
    request.extraInfo = info;
    request.adType = CXHAdFormatNative;
    request.UUID = requestUUID;
    
    if (isExpress) {
        CXHTopOnNativeExpressEvent *customEvent = [[CXHTopOnNativeExpressEvent alloc] initWithInfo:info localInfo:info];
        customEvent.isC2SBiding = YES;
        customEvent.networkAdvertisingID = posid;
        customEvent.UUID = requestUUID;
        
        request.customEvent = customEvent;
    } else {
        CXHTopOnNativeEvent *customEvent = [[CXHTopOnNativeEvent alloc] initWithInfo:info localInfo:info];
        customEvent.isC2SBiding = YES;
        customEvent.networkAdvertisingID = posid;
        customEvent.UUID = requestUUID;
        
        request.customEvent = customEvent;
    }
    
    [[CXHTopOnCommonBiddingManager sharedInstance]startWithRequestItem:request];
    
}

//// 返回广告位比价胜利时，第二的价格的回调，可在该回调中向三方平台返回竞胜价格  secondPrice：美元(USD)
+ (void) sendWinnerNotifyWithCustomObject:(id)customObject secondPrice:(NSString*)price userInfo:(NSDictionary<NSString *, NSString *> *)userInfo {
    if ([customObject isKindOfClass:CXHAdSDKNativeExpressAd.class]) {
        NSLog(@"------> menta nativeexpress ad win");
        CXHAdSDKNativeExpressAd *nativeExpressAd = (CXHAdSDKNativeExpressAd *)customObject;
        [nativeExpressAd sendWinNotice:[price integerValue]];
    } else {
        NSLog(@"------> menta native ad win");
        CXHAdSDKNativeAd *nativeAd = (CXHAdSDKNativeAd *)customObject;
        [nativeAd sendWinNotice:[price integerValue]];
    }
}

//// 返回广告位比价输了的回调，可在该回调中向三方平台返回竞败价格 winPrice：美元(USD)
+ (void)sendLossNotifyWithCustomObject:(nonnull id)customObject lossType:(ATBiddingLossType)lossType winPrice:(nonnull NSString *)price userInfo:(NSDictionary *)userInfo {
    if ([customObject isKindOfClass:CXHAdSDKNativeExpressAd.class]) {
        NSLog(@"------> menta nativeexpress ad loss");
        CXHAdSDKNativeExpressAd *nativeExpressAd = (CXHAdSDKNativeExpressAd *)customObject;
        [nativeExpressAd sendLossNotice:[price integerValue]];
    } else {
        NSLog(@"------> menta native ad loss");
        CXHAdSDKNativeAd *nativeAd = (CXHAdSDKNativeAd *)customObject;
        [nativeAd sendLossNotice:[price integerValue]];
    }
}

#pragma mark - private method
+ (void)initCXHSDKWith:(NSString*)appid domain:(NSString *)domain completion:(void (^)(void))completion {
    NSLog(@"====== start init cxh sdk");
    [CXHAdSDK initWithAppId:appid requestDomain:domain completionBlock:^(NSError * _Nullable error) {
        if (!error && completion != nil) {
            completion();
        }
    }];
}

- (void)dealloc
{
    NSLog(@"------> %s", __FUNCTION__);
}

@end
